home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Future Workshop
/
Future Workshop.iso
/
multimed
/
qtw111
/
pviewer
/
zoomctrl.c
< prev
Wrap
C/C++ Source or Header
|
1994-01-11
|
29KB
|
760 lines
// ---------------------------------------------------------------------
//
// ZoomCtrl.c - Picture Viewer - QuickTime for Windows
//
// Version 1.0
//
// (c) 1988-1992 Apple Computer, Inc. All Rights Reserved.
//
// ---------------------------------------------------------------------
// Includes
// --------
#define NOMINMAX
#include <Windows.H> // Required by Windows
#include <stdlib.h> // Required for abs function
#include <qtole.h> // Interface to qtole dll
#include <qtw.h> // Interface to QuickTime
// Needed for struct defs in picture.h
#include "common.h" // Interface to common.c
#include "viewer.h" // Interface to *.c files
#include "viewer.hr" // Defines used in *.rc files
#include "picture.h" // Interface to picture window
// child window processing
// Consts
// ---------
// These are used instead of GetSysColors because user may change
// system colors using control panel in which case, our colors would
// no longer match the Windows button colors which do not change
#define BTNFACECOLOR (RGB( 192, 192, 192 ))
#define BTNSHADOWCOLOR (RGB( 128, 128, 128 ))
#define BTNHIGHLIGHTCOLOR (RGB( 255, 255, 255 ))
#define TEXT_HEIGHT 7 // Text height in points
#define TEXT_EXTRA_SPACING 2 // Extra spacing between characters in
// percent text
// This struct defines the bounds of the zones used by the zoom control
typedef struct // Hungarian notation: zns
{POINT ptBuckle; // position of UL corner of buckle
// in the corresponding zone
WORD wZoomMultiplier; // Zoom scaling multiplier
char szPercent[8]; // percent text i.e. "150% "
// This string is padded with with blanks
} ZONES, * NPZONES;
// Message-Persistent Data
// -----------------------
static struct // Hungarian notation: g
{ // These bitmaps and dimensions are used in the zoom control
// They are shared by all instances
RECT rcBar; // Rect defining belt in control
RECT rcYard; // Rect defining area in which mouse
// dragging works. When the mouse is
// dragged outside this rect, the
// buckle does not follow
HBITMAP hbmpActiveBuckle; // Handle to active buckle bitmap
WORD wBuckleWidth; // Width of buckle bitmap
WORD wBuckleHeight; // Height of buckle bitmap
ZONES znsZones[NUM_OF_ZOOMS]; // Array of zone structs
POINT ptText; // Upper-Left corner of % text
int nTextHeight; // % Text height
WORD wWidthWnd; // Adjusted window width after
// correcting for font size
} g;
// Internal Function Declarations
// ------------------------------
static LONG NEAR BuildBuckleStuff (HWND);
static LONG NEAR UpdateBuckleAndText (HWND, HDC, NPPICTUREDATA, WORD,
HBITMAP, BOOL, BOOL);
static VOID NEAR Draw3DRect (HDC, int, int, int, int);
static LONG NEAR DrawBuckle (HDC, NPPICTUREDATA, NPZONES,
HBITMAP, BOOL, BOOL);
static WORD NEAR PointToZoomIndex (PPOINT, WORD);
// Function: PictureZoomWndProc - Window proc for the picture resizing
// scroll bar
// --------------------------------------------------------------------
// Parameters: As required by Microsoft Windows
//
// Returns: Via DefWindowProc
// --------------------------------------------------------------------
LONG __export CALLBACK PictureZoomWndProc
(HWND hwndZoom, UINT message, WPARAM wParam, LPARAM lParam)
{ // These statics are only used during mouse capture
static BOOL bDragging; // Dragging flag
static WORD wZoomIndex; // Current zoom index during dragging
NPPICTUREDATA pPictureData; // -> picture data struct
PAINTSTRUCT ps; // Paint struct
HDC hdc; // Control dc
RECT rcZoom; // Client rect of control
HWND hwndPicture; // Handle of picture window
HBRUSH hbrush; // Handle of brush
HBRUSH hbrushSave; // Handle of prev brush
NPZONES pznsZone; // -> zone struct
POINT ptMouse; // Mouse position
WORD wNewZoomIndex; // New zoom index
RECT rcBuckle; // Buckle rect
if( !(pPictureData = (NPPICTUREDATA)
GetWindowWord( hwndPicture = GetParent( hwndZoom ), 0 )))
return DefWindowProc( hwndZoom, message, wParam, lParam);
switch( message ) {
case WM_CREATE:
// Set statics: rcBar, zones and bitmaps for buckle
// This data is shared by all instances
if( !g.hbmpActiveBuckle && BuildBuckleStuff( hwndZoom ))
return -1L;
// Create a bitmap that will save the area under the buckle
// Each instance gets one of these
if( !( hdc = GetDC( hwndZoom ))) {
CommonTellUser( ViewerQueryResources(),
VIEWER_STRING_NODC, VIEWER_STRING_CAPTION, MB_OK );
return 0L;
}
if( !(pPictureData->zsZoomScroll.hbmpNotBuckle =
CreateCompatibleBitmap( hdc,
g.wBuckleWidth, g.wBuckleHeight ))) {
CommonTellUser( ViewerQueryResources(),
VIEWER_STRING_NOMEMORY, NULL, MB_OK );
ReleaseDC( hwndZoom, hdc );
return -1L;
}
ReleaseDC( hwndZoom, hdc );
return 0L;
case WM_KEYDOWN:
switch( wParam ) {
case VK_ADD:
case VK_SUBTRACT:
wZoomIndex =
pPictureData->zsZoomScroll.wCurZoomIndex +
((wParam == VK_ADD) ? 1 : -1);
if( (wZoomIndex < IMAGE_SIZE_FIRST ) ||
(wZoomIndex >= IMAGE_SIZE_FIRST + NUM_OF_ZOOMS))
return 0L;
if( !(hdc = GetDC( hwndZoom ))) {
CommonTellUser( ViewerQueryResources(),
VIEWER_STRING_NODC,
VIEWER_STRING_CAPTION, MB_OK );
return 0L;
}
UpdateBuckleAndText( hwndZoom, hdc, pPictureData,
wZoomIndex, g.hbmpActiveBuckle, FALSE, TRUE );
ReleaseDC( hwndZoom, hdc );
ZoomPicture( hwndPicture, wZoomIndex );
return 0L;
default:
break;
}
break;
case WM_LBUTTONDOWN:
ptMouse = MAKEPOINT( lParam );
if( !PtInRect( &g.rcBar, ptMouse ))
return 0L;
wZoomIndex = PointToZoomIndex( &ptMouse,
pPictureData->zsZoomScroll.wCurZoomIndex );
if( wZoomIndex != pPictureData->zsZoomScroll.wCurZoomIndex ) {
if( !(hdc = GetDC( hwndZoom ))) {
CommonTellUser( ViewerQueryResources(),
VIEWER_STRING_NODC,
VIEWER_STRING_CAPTION, MB_OK );
return 0L;
}
UpdateBuckleAndText( hwndZoom, hdc, pPictureData,
wZoomIndex, g.hbmpActiveBuckle, FALSE, TRUE );
ReleaseDC( hwndZoom, hdc );
}
SetCapture( hwndZoom );
bDragging = TRUE;
return 0L;
case WM_LBUTTONUP:
if( bDragging ) {
ReleaseCapture();
ZoomPicture( hwndPicture, wZoomIndex );
}
bDragging = FALSE;
return 0L;
case WM_MOUSEMOVE:
if( !bDragging )
return 0L;
ptMouse = MAKEPOINT( lParam );
if( PtInRect( &g.rcYard, ptMouse )) {
if( wZoomIndex == ( wNewZoomIndex =
PointToZoomIndex( &ptMouse, wZoomIndex )))
return 0L;
}
else {
wNewZoomIndex = pPictureData->zsZoomScroll.wCurZoomIndex;
}
wZoomIndex = wNewZoomIndex;
if( !(hdc = GetDC( hwndZoom ))) {
CommonTellUser( ViewerQueryResources(),
VIEWER_STRING_NODC, VIEWER_STRING_CAPTION, MB_OK );
return 0L;
}
UpdateBuckleAndText( hwndZoom, hdc, pPictureData, wZoomIndex,
g.hbmpActiveBuckle, FALSE, TRUE );
ReleaseDC( hwndZoom, hdc );
return 0L;
// WM_USER messages
case WM_ZOOM_MOVEBUCKLE:
if( !(hdc = GetDC( hwndZoom ))) {
CommonTellUser( ViewerQueryResources(),
VIEWER_STRING_NODC, VIEWER_STRING_CAPTION, MB_OK );
return 0L;
}
UpdateBuckleAndText( hwndZoom, hdc, pPictureData,
pPictureData->zsZoomScroll.wCurZoomIndex,
g.hbmpActiveBuckle, FALSE, TRUE );
ReleaseDC( hwndZoom, hdc );
return 0L;
// End WM_USER messages
case WM_PAINT:
pznsZone = g.znsZones +
pPictureData->zsZoomScroll.wCurZoomIndex -
IMAGE_SIZE_FIRST;
// Force repaint of the buckle to prevent the
// repainting logic from getting off
*((LPPOINT) &rcBuckle.left) =
pPictureData->zsZoomScroll.ptBucklePos;
rcBuckle.right = rcBuckle.left + g.wBuckleWidth;
rcBuckle.bottom = rcBuckle.top + g.wBuckleHeight;
InvalidateRect( hwndZoom, &rcBuckle, TRUE );
if( !BeginPaint( hwndZoom, &ps ))
return 0L;
GetClientRect( hwndZoom, &rcZoom );
// Draw the main rect
if( !( hbrush = CreateSolidBrush( BTNFACECOLOR ))) {
EndPaint( hwndZoom, &ps );
return 0L;
}
FillRect( ps.hdc, &rcZoom, hbrush );
DeleteObject( hbrush );
// Draw the belt
if( !( hbrush = CreateSolidBrush( BTNSHADOWCOLOR ))) {
EndPaint( hwndZoom, &ps );
return 0L;
}
hbrushSave = SelectObject( ps.hdc, hbrush );
Rectangle( ps.hdc, g.rcBar.left, g.rcBar.top,
g.rcBar.right, g.rcBar.bottom );
DeleteObject( SelectObject( ps.hdc, hbrushSave ));
// Draw the buckle
UpdateBuckleAndText( hwndZoom, ps.hdc, pPictureData,
pPictureData->zsZoomScroll.wCurZoomIndex,
g.hbmpActiveBuckle, TRUE, TRUE );
EndPaint( hwndZoom, &ps );
return 0L;
case WM_DESTROY:
// Each instance has one of these
if( pPictureData->zsZoomScroll.hbmpNotBuckle ) {
DeleteObject( pPictureData->zsZoomScroll.hbmpNotBuckle );
pPictureData->zsZoomScroll.hbmpNotBuckle = NULL;
}
// All instances share these
if( ViewerQueryNumPictures() <= 1 ) {
if( g.hbmpActiveBuckle )
DeleteObject( g.hbmpActiveBuckle );
g.hbmpActiveBuckle = NULL;
}
pPictureData->zsZoomScroll.hwnd = NULL;
return 0L;
default:
break;
}
return DefWindowProc( hwndZoom, message, wParam, lParam);
}
// Function: UpdateBuckleAndText - Draws the buckle and text
// --------------------------------------------------------------------
// Parameters: HWND hwndZoom Window handle of control
// HDC hdc DC of control
// NPPICTUREDATA pPictureData -> picture data struct
// WORD wZoomIndex Current zoom index
// HBITMAP hbmpBuckle Handle of buckle bitmap
// BOOL bRepainting Repainting flag
// BOOL bUpdateNoBuckle Update no buckle bitmap flag
//
// Returns: LONG 0L if OK
// --------------------------------------------------------------------
static LONG NEAR UpdateBuckleAndText( HWND hwndZoom,
HDC hdc, NPPICTUREDATA pPictureData,
WORD wZoomIndex, HBITMAP hbmpBuckle,
BOOL bRepainting, BOOL bUpdateNoBuckle )
{
NPZONES pznsZone; // -> zone struct
HFONT hFont; // Handle to font used for % text
HFONT hsaveFont; // Prev font
COLORREF dwcrSave; // Prev color
UINT uSaveAlign; // Prev text alignment
pznsZone = g.znsZones + wZoomIndex - IMAGE_SIZE_FIRST;
// Draw the buckle in the new position
if( DrawBuckle(hdc, pPictureData, pznsZone, hbmpBuckle,
bRepainting, bUpdateNoBuckle ))
return 0L;
// Get the font. Don't bother with error message. If this
// fails, the system font will be used
if( hFont = MakeAnArialFont( hdc, g.nTextHeight ))
hsaveFont = SelectObject( hdc, hFont );
SetTextCharacterExtra( hdc,
GetTextCharacterExtra( hdc ) + TEXT_EXTRA_SPACING );
dwcrSave = SetBkColor( hdc, BTNFACECOLOR );
// Draw the % text
uSaveAlign = SetTextAlign( hdc, TA_LEFT | TA_BASELINE );
TextOut( hdc, g.ptText.x, g.ptText.y, pznsZone->szPercent,
lstrlen( pznsZone->szPercent ));
SetTextAlign( hdc, uSaveAlign );
if( hFont )
DeleteObject( SelectObject( hdc, hsaveFont ));
SetBkColor( hdc, dwcrSave );
return 0L;
}
// Function: DrawBuckle - Draws the buckle
// --------------------------------------------------------------------
// Parameters: HDC hdc hdc of control
// NPPICTUREDATA pPictureData -> to picturedata struct
// NPZONES pznsZone -> zone struct. Contains
// offsets used to position buckle
// HBITMAP hbmpBuckle Buckle bitmap
// BOOL bRepainting TRUE if WM_PAINT message
// BOOL bUpdateNoBuckle TRUE if area under buckle
// should be saved. This is
// false if only changing
// activation state of buckle
//
// Returns: LONG 0L if OK
// --------------------------------------------------------------------
static LONG NEAR DrawBuckle( HDC hdc, NPPICTUREDATA pPictureData,
NPZONES pznsZone, HBITMAP hbmpBuckle,
BOOL bRepainting, BOOL bUpdateNoBuckle )
{
HDC hdcMem; // Memory device context
HBITMAP hbmpSave; // Prev bitmap
if( !(hdcMem = CreateCompatibleDC( hdc ))) {
CommonTellUser( ViewerQueryResources(),
VIEWER_STRING_NODC, VIEWER_STRING_CAPTION, MB_OK );
return VIEWER_STRING_NODC;
}
hbmpSave = SelectObject( hdcMem,
pPictureData->zsZoomScroll.hbmpNotBuckle );
// Use no buckle bitmap to remove buckle
if( !bRepainting ) {
BitBlt( hdc, pPictureData->zsZoomScroll.ptBucklePos.x,
pPictureData->zsZoomScroll.ptBucklePos.y,
g.wBuckleWidth, g.wBuckleHeight,
hdcMem, 0, 0, SRCCOPY );
}
// Save area under new position of buckle
if( bUpdateNoBuckle ) {
BitBlt( hdcMem, 0, 0, g.wBuckleWidth, g.wBuckleHeight,
hdc, pznsZone->ptBuckle.x, pznsZone->ptBuckle.y, SRCCOPY );
pPictureData->zsZoomScroll.ptBucklePos = pznsZone->ptBuckle;
}
// Draw buckle
SelectObject( hdcMem, hbmpBuckle );
BitBlt( hdc, pznsZone->ptBuckle.x, pznsZone->ptBuckle.y,
g.wBuckleWidth, g.wBuckleHeight, hdcMem, 0, 0, SRCCOPY );
SelectObject( hdcMem, hbmpSave );
DeleteDC( hdcMem );
return 0L;
}
// Function: BuildBuckleStuff - processes WM_CREATE message for
// zoom wnd control
// --------------------------------------------------------------------
// Parameters: HWND hwndZoom Window handle of zoom control
//
// Returns: LONG 0L if OK
// --------------------------------------------------------------------
static LONG NEAR BuildBuckleStuff( HWND hwndZoom )
{
RECT rcClient; // Client rect of window
POINT ptBuckle; // Temp UL corner of buckle
WORD wBar; // Length of bar
WORD wBar1; // Temp length of bar
WORD wBar2; // Temp length of bar
WORD wBuckleP1; // Width of buckle + 1 pixel
HDC hdc; // Device context of control
HDC hdcMem; // Memory dc
HBITMAP hbmpSave; // Prev bitmap
char szFormat[6]; // Resource string format for % text
int i; // Temp index
int j; // Temp index
WORD wBarHeight; // Bar height
WORD wBuckleExtension; // Half the amount by which buckle height exceeds
// bar height
WORD wMaxTextExtent; // Max text extent of % text
WORD wTextExtent; // Text extent of % text
HFONT hFont; // Font used to display % text
HFONT hsaveFont; // Prev font
TEXTMETRIC tm; // Text metrics struct
BOOL bGotTextMetrics; // TRUE if GetTextMetrics worked
WORD wAveChar; // Average width of % text char
int nMaxTextHeight; // Max text height
static WORD wZoomMults[NUM_OF_ZOOMS] = // Array of zoom multipliers
{ 25, 50, 75, 100, 150, 200, 400 }; // that define the scaling
GetClientRect( hwndZoom, &rcClient );
// rcYard defines the area within which the control responds to
// mouse dragging
g.rcYard = rcClient;
g.rcYard.left -= (WORD) GetSystemMetrics( SM_CXVSCROLL );
g.rcYard.right += (WORD) GetSystemMetrics( SM_CXVSCROLL );
g.rcYard.top -= (WORD) GetSystemMetrics( SM_CYHSCROLL );
g.rcYard.bottom += (WORD) GetSystemMetrics( SM_CYHSCROLL );
// Set rect for slider bar
g.rcBar.left = rcClient.bottom / 3;
g.rcBar.right = g.rcBar.left + (65 * rcClient.right / 100 );
g.rcBar.top = max( 3 * rcClient.bottom / 10, 3 );
g.rcBar.bottom = rcClient.bottom - g.rcBar.top;
wBar = g.rcBar.right - g.rcBar.left;
wBarHeight = g.rcBar.bottom - g.rcBar.top;
wBuckleExtension = ( rcClient.bottom - wBarHeight - 2 ) / 2;
if( wBuckleExtension > 2 )
wBuckleExtension = 2;
g.wBuckleHeight = wBarHeight + 2 * wBuckleExtension;
// Set buckle width and then adjust bar or buckle length so that
// bar length is integral number of buckles long + 2 pixels
g.wBuckleWidth = ( wBar - NUM_OF_ZOOMS - 1 ) / NUM_OF_ZOOMS;
wBar1 = ( g.wBuckleWidth + 1 ) * NUM_OF_ZOOMS + 1;
wBar2 = ( (g.wBuckleWidth + 1) + 1 ) * NUM_OF_ZOOMS + 1;
if( abs( wBar - wBar1 ) >= abs( wBar - wBar2 )) {
g.wBuckleWidth += 1;
g.rcBar.right = g.rcBar.left + wBar2;
}
else {
g.rcBar.right = g.rcBar.left + wBar1;
}
if( !(hdc = GetDC( hwndZoom ))) {
CommonTellUser( ViewerQueryResources(),
VIEWER_STRING_NODC, VIEWER_STRING_CAPTION, MB_OK );
return VIEWER_STRING_NODC;
}
// Set zones
// Initialize text strings
LoadString( ViewerQueryResources(), VIEWER_STRING_PERCENT,
szFormat, sizeof( szFormat ));
wMaxTextExtent = 0;
// Set text height
g.nTextHeight = -MulDiv( TEXT_HEIGHT,
GetDeviceCaps( hdc, LOGPIXELSY ), 72 );
// Limit text height to 2/3 of the window height
nMaxTextHeight = -MulDiv( 2, rcClient.bottom, 3 );
// use max because values are < 0
g.nTextHeight = max( g.nTextHeight, nMaxTextHeight );
// Select font into dc so GetTextExtent will work
if( hFont = MakeAnArialFont( hdc, g.nTextHeight ))
hsaveFont = SelectObject( hdc, hFont );
SetTextCharacterExtra( hdc,
GetTextCharacterExtra( hdc ) + TEXT_EXTRA_SPACING );
for( i=0; i < NUM_OF_ZOOMS; i++ ) { // Save multipliers for Query function
g.znsZones[i].wZoomMultiplier = wZoomMults[i];
wsprintf( g.znsZones[i].szPercent, szFormat,
g.znsZones[i].wZoomMultiplier );
// Get text extent before padding with blanks
wTextExtent = LOWORD( GetTextExtent( hdc, g.znsZones[i].szPercent,
lstrlen( g.znsZones[i].szPercent )));
if( wMaxTextExtent < wTextExtent ) {
wMaxTextExtent = wTextExtent;
wAveChar = wMaxTextExtent / lstrlen( g.znsZones[i].szPercent );
}
// Now pad with blanks to erase previous text
for(j=lstrlen( g.znsZones[i].szPercent );
j < sizeof( g.znsZones[i].szPercent ) - 1; j++ )
g.znsZones[i].szPercent[j] = ' ';
g.znsZones[i].szPercent[j] = '\0';
}
bGotTextMetrics = GetTextMetrics( hdc, &tm );
if( hFont )
DeleteObject( SelectObject( hdc, hsaveFont ));
// Initialize buckle positions and zone edges
wBuckleP1 = g.wBuckleWidth + 1;
ptBuckle.x = g.rcBar.left + 1;
ptBuckle.y = g.rcBar.top - wBuckleExtension;
for( i=0; i < NUM_OF_ZOOMS; i++ ) {
g.znsZones[i].ptBuckle = ptBuckle;
ptBuckle.x += wBuckleP1;
}
if( !(hdcMem = CreateCompatibleDC( hdc ))) {
ReleaseDC( hwndZoom, hdc );
CommonTellUser( ViewerQueryResources(),
VIEWER_STRING_NODC, VIEWER_STRING_CAPTION, MB_OK );
return VIEWER_STRING_NODC;
}
// build buckle
if( !( g.hbmpActiveBuckle = CreateCompatibleBitmap
( hdc, g.wBuckleWidth, g.wBuckleHeight ))) {
DeleteDC( hdcMem );
ReleaseDC( hwndZoom, hdc );
CommonTellUser( ViewerQueryResources(),
VIEWER_STRING_NOMEMORY, NULL, MB_OK );
return VIEWER_STRING_NOMEMORY;
}
hbmpSave = SelectObject( hdcMem, g.hbmpActiveBuckle );
Draw3DRect( hdcMem, 0, 0, g.wBuckleWidth, g.wBuckleHeight );
SelectObject( hdcMem, hbmpSave );
DeleteDC( hdcMem );
// Set reference point for TextOut
g.ptText.x = g.rcBar.right + 4;
if( bGotTextMetrics ) {
g.ptText.y = max( g.rcBar.bottom,
( rcClient.bottom +
tm.tmAscent - tm.tmInternalLeading ) / 2 );
}
else {
g.ptText.y = g.rcBar.bottom;
}
// Now make sure text will fit in window, adjust width if it doesn't
g.wWidthWnd = g.ptText.x + wMaxTextExtent + ( 3 * wAveChar / 2 );
ReleaseDC( hwndZoom, hdc );
return 0L;
}
// Function: Draw3DRect - Draws the 3D stuff on a given rect
// --------------------------------------------------------------------
// Parameters: HDC hdc Device context
// int left Rect.left
// int top Rect.top
// int right Rect.right
// int bottom Rect.bottom
//
// Returns: VOID
// --------------------------------------------------------------------
static VOID NEAR Draw3DRect( HDC hdc,
int nleft, int ntop, int nright, int nbottom )
{
HPEN hpenSave; // Prev pen
HPEN hpenHighLite; // HighLite pen
HPEN hpenShadow; // Shadow pen
HBRUSH hbrush; // Brush
HBRUSH hbrushSave; // Prev brush
// Don't bother with error messages. Failure here will not cause a
// crash. The rects just won't look right.
if( hbrush = CreateSolidBrush( BTNFACECOLOR )) {
hbrushSave = SelectObject( hdc, hbrush );
Rectangle( hdc, nleft, ntop, nright, nbottom );
DeleteObject( SelectObject( hdc, hbrushSave ));
}
if( hpenShadow = CreatePen( PS_SOLID, 1, BTNSHADOWCOLOR)) {
hpenSave = SelectObject( hdc, hpenShadow );
MoveTo( hdc, nright - 2, 1 );
LineTo( hdc, nright - 2, nbottom - 2 );
LineTo( hdc, 0, nbottom - 2);
DeleteObject( SelectObject( hdc, hpenSave ));
}
if( hpenHighLite = CreatePen( PS_SOLID, 1, BTNHIGHLIGHTCOLOR )) {
hpenSave = SelectObject( hdc, hpenHighLite );
MoveTo( hdc, 1, nbottom - 3 );
LineTo( hdc, 1, 1 );
LineTo( hdc, nright - 2, 1 );
DeleteObject( SelectObject( hdc, hpenSave ));
}
return;
}
// Function: PointToZoomIndex - Finds index of zoon cooresponding to mouse
// position
// --------------------------------------------------------------------
// Parameters: PPOINT pptMouse -> current mouse position
// WORD wCurZoneIndex Current zone index
//
// Returns: WORD wZoomIndex
// --------------------------------------------------------------------
static WORD NEAR PointToZoomIndex( PPOINT pptMouse, WORD wCurZoneIndex )
{
int nxPos; // Horizontal position of mouse
WORD iCur; // Current zone -> offset
WORD i; // Counter
int nWidthP1; // Width of buckle + 1 pixel
nxPos = pptMouse->x;
nWidthP1 = g.wBuckleWidth + 1;
iCur = wCurZoneIndex - IMAGE_SIZE_FIRST;
// Check if left of first zone
if( nxPos <= g.znsZones[0].ptBuckle.x + nWidthP1)
return IMAGE_SIZE_FIRST;
// Check if in current zone
if( ( nxPos >= g.znsZones[iCur].ptBuckle.x - 1 ) &&
( nxPos <= g.znsZones[iCur].ptBuckle.x + nWidthP1 ))
return wCurZoneIndex;
// Check rest of zones
for(i=0; i < NUM_OF_ZOOMS; i++ ) {
if(( i != iCur ) &&
( nxPos <= g.znsZones[i].ptBuckle.x + nWidthP1 ))
return ( i + IMAGE_SIZE_FIRST );
}
return ( IMAGE_SIZE_FIRST + NUM_OF_ZOOMS - 1 );
}
// The remaining functions are the query functions called by other modules
// Function: ViewerQueryZoomMultiplier - Query the zoom multiplier for the
// current zoom index
// --------------------------------------------------------------------
// Parameters: WORD wZoomIndex Current zoom index
//
// Returns: WORD wZoomMult Corresponding zoom muliplier
// --------------------------------------------------------------------
WORD FAR ViewerQueryZoomMultiplier( WORD wZoomIndex )
{
return g.znsZones[wZoomIndex - IMAGE_SIZE_FIRST].wZoomMultiplier;
}
// Function: ViewerQueryZoomIndex - Query the zoom index for the
// current zoom multiplier
// --------------------------------------------------------------------
// Parameters: WORD wZoomMult Current zoom muliplier
//
// Returns: WORD wZoomIndex Corresponding zoom index
// --------------------------------------------------------------------
WORD FAR ViewerQueryZoomIndex( WORD wZoomMultiplier )
{
int i;
for( i=0; i < NUM_OF_ZOOMS - 1; i++ ) {
if( wZoomMultiplier <= g.znsZones[i].wZoomMultiplier )
break;
}
return ( i + IMAGE_SIZE_FIRST );
}
// Function: ViewerQueryZoomWndWidth - Query the final width of the
// zoom window after adjustment for
// font (see BuildBuckleStuff())
// --------------------------------------------------------------------
// Parameters: VOID
//
// Returns: WORD wWidthWnd final width of control
// --------------------------------------------------------------------
WORD FAR ViewerQueryZoomWndWidth( VOID )
{
return g.wWidthWnd;
}